$import( "SmitearWebGL.Core.ResourceItem" );

SmitearWebGL.Resources.MaterialLayer = SmitearWebGL.Core.ResourceItem.extend(
{
	/******** constructor ********/

	init : function()
	{
		this._super();
		this._registClass( "SmitearWebGL.Resources.MaterialLayer" );
		
		/******** public property ********/
		
		this.blendMode = null;
		this.mapinput = SmitearWebGL.Resources.MaterialLayer.UV1;
		this.height = 0.05;
		
		/******** private property ********/

		this._mapto = null;
		
		this._offset = null;
		this._rotation = null;
		this._scale = null;
		
		this._dOffset = null;
		this._dRotation = null;
		this._dScale = null;
		
		this._texture = null;
		this._matrix = null;
		
		this._transformDirty = false;
	}
	,

	/******** public method ********/
	
	glUniform : function( field, shader )
	{
		switch( field )
		{
			case SmitearWebGL.ShaderUniform.layerMatrix:
				this.context.gl.uniformMatrix4fv( shader.uniforms["uLayer" + this.getResourceHandle() + "Matrix"].location, false, new Float32Array( this.getMatrix().flatten() ) );
				break;
				
			case SmitearWebGL.ShaderUniform.layerHeight:
				this.context.gl.uniform1f( shader.uniforms["uLayerheight" + this.getResourceHandle()].location, this.height );
				break;
		}
	}
	,
	setOffsetX : function( value )
	{
		this._offset.x = value;
		this._transformDirty = true;
	}
	,
	setOffsetY : function( value )
	{
		this._offset.y = value;
		this._transformDirty = true;
	}
	,
	setOffsetZ : function( value )
	{
		this._offset.z = value;
		this._transformDirty = true;
	}
	,
	getOffsetX : function()
	{
		return this._offset.x;
	}
	,
	getOffsetY : function()
	{
		return this._offset.y;
	}
	,
	getOffsetZ : function()
	{
		return this._offset.z;
	}
	,
	setRotationX : function( value )
	{
		this._rotation.x = value;
		this._transformDirty = true;
	}
	,
	setRotationY : function( value )
	{
		this._rotation.y = value;
		this._transformDirty = true;
	}
	,
	setRotationZ : function( value )
	{
		this._rotation.z = value;
		this._transformDirty = true;
	}
	,
	getRotationX : function()
	{
		return this._rotation.x;
	}
	,
	getRotationY : function()
	{
		return this._rotation.y;
	}
	,
	getRotationZ : function()
	{
		return this._rotation.z;
	}
	,
	setScaleX : function( value )
	{
		this._scale.x = value;
		this._transformDirty = true;
	}
	,
	setScaleY : function( value )
	{
		this._scale.y = value;
		this._transformDirty = true;
	}
	,
	setScaleZ : function( value )
	{
		this._scale.z = value;
		this._transformDirty = true;
	}
	,
	setScale : function( value )
	{
		this._scale.x = value;
		this._scale.y = value;
		this._scale.z = value;
		this._transformDirty = true;
	}
	,
	getScaleX : function()
	{
		return this._scale.x;
	}
	,
	getScaleY : function()
	{
		return this._scale.y;
	}
	,
	getScaleZ : function()
	{
		return this._scale.z;
	}
	,
	setDOffsetX : function( value )
	{
		this._dOffset.x = value;
		this._transformDirty = true;
	}
	,
	setDOffsetY : function( value )
	{
		this._dOffset.y = value;
		this._transformDirty = true;
	}
	,
	setDOffsetZ : function( value )
	{
		this._dOffset.z = value;
		this._transformDirty = true;
	}
	,
	getDOffsetX : function()
	{
		return this._dOffset.x;
	}
	,
	getDOffsetY : function()
	{
		return this._dOffset.y;
	}
	,
	getDOffsetZ : function()
	{
		return this._dOffset.z;
	}
	,
	setDRotationX : function( value )
	{
		this._dRotation.x = value;
		this._transformDirty = true;
	}
	,
	setDRotationY : function( value )
	{
		this._dRotation.y = value;
		this._transformDirty = true;
	}
	,
	setDRotationZ : function( value )
	{
		this._dRotation.z = value;
		this._transformDirty = true;
	}
	,
	getDRotationX : function()
	{
		return this._dRotation.x;
	}
	,
	getDRotationY : function()
	{
		return this._dRotation.y;
	}
	,
	getDRotationZ : function()
	{
		return this._dRotation.z;
	}
	,
	setDScaleX : function( value )
	{
		this._dScale.x = value;
		this._transformDirty = true;
	}
	,
	setDScaleY : function( value )
	{
		this._dScale.y = value;
		this._transformDirty = true;
	}
	,
	setDScaleZ : function( value )
	{
		this._dScale.z = value;
		this._transformDirty = true;
	}
	,
	setDScale : function( value )
	{
		this._dScale.x = value;
		this._dScale.y = value;
		this._dScale.z = value;
		this._transformDirty = true;
	}
	,
	getDScaleX : function()
	{
		return this._dScale.x;
	}
	,
	getDScaleY : function()
	{
		return this._dScale.y;
	}
	,
	getDScaleZ : function()
	{
		return this._dScale.z;
	}
	,
	getRotation : function()
	{
		return SmitearWebGL.Core.Math.Vector3.add( this._rotation, this._dRotation );
	}
	,
	getOffset : function()
	{
		return SmitearWebGL.Core.Math.Vector3.add( this._offset, this._dOffset );
	}
	,
	getScale : function()
	{
		return SmitearWebGL.Core.Math.Vector3.add( this._scale, this._dScale );
	}
	,
	setTexture : function( texture )
	{
		this._texture = texture;
	}
	,
	getTexture : function()
	{
		return this._texture;
	}
	,
	getMatrix : function()
	{
		if( ! this._matrix )
		{
			var offset = this.getOffset();
			var scale = this.getScale();
			var rotation = this.getRotation();
			this._matrix = SmitearWebGL.Core.Math.Matrix4x4.scale( scale.x, scale.y, scale.z );
			this._matrix.calculateMultiply( SmitearWebGL.Core.Math.Matrix4x4.rotationMatrix( rotation.x, rotation.y, rotation.z ), this._matrix);
			this._matrix.calculateMultiply( SmitearWebGL.Core.Math.Matrix4x4.translation( offset.x, offset.y, offset.z ), this._matrix);
		}
		return this._matrix;
	}
	,
	mapToHeight : function( bool )
	{
		this._mapto.setBit( SmitearWebGL.Resources.MaterialLayer.M_HEIGHT, bool );
	}
	,
	mapToDiffuse : function( bool )
	{
		this._mapto.setBit( SmitearWebGL.Resources.MaterialLayer.M_DIFFUSE, bool );
	}
	,
	mapToSpecular : function( bool )
	{
		this._mapto.setBit( SmitearWebGL.Resources.MaterialLayer.M_SPECULAR, bool );
	}
	,
	mapToEmissive : function( bool )
	{
		this._mapto.setBit( SmitearWebGL.Resources.MaterialLayer.M_EMISSIVE, bool );
	}
	,
	mapToMask : function( bool )
	{
		this._mapto.setBit( SmitearWebGL.Resources.MaterialLayer.M_MASK, bool );
	}
	,
	mapToReflective : function( bool )
	{
		this._mapto.setBit( SmitearWebGL.Resources.MaterialLayer.M_REFLECTIVE, bool );
	}
	,
	mapToShininess : function( bool )
	{
		this._mapto.setBit( SmitearWebGL.Resources.MaterialLayer.M_SHININESS, bool );
	}
	,
	mapToAlpha : function( bool )
	{
		this._mapto.setBit( SmitearWebGL.Resources.MaterialLayer.M_ALPHA, bool );
	}
	,
	mapToNormal : function( bool )
	{
		this._mapto.setBit( SmitearWebGL.Resources.MaterialLayer.M_NORMAL, bool );
	}
	,
	isMapToHeight : function()
	{
		return this._mapto.testBit( SmitearWebGL.Resources.MaterialLayer.M_HEIGHT );
	}
	,
	isMapToDiffuse : function()
	{
		return this._mapto.testBit( SmitearWebGL.Resources.MaterialLayer.M_DIFFUSE );
	}
	,
	isMapToSpecular : function()
	{
		return this._mapto.testBit( SmitearWebGL.Resources.MaterialLayer.M_SPECULAR );
	}
	,
	isMapToEmissive : function()
	{
		return this._mapto.testBit( SmitearWebGL.Resources.MaterialLayer.M_EMISSIVE );
	}
	,
	isMapToMask : function()
	{
		return this._mapto.testBit( SmitearWebGL.Resources.MaterialLayer.M_MASK );
	}
	,
	isMapToReflective : function()
	{
		return this._mapto.testBit( SmitearWebGL.Resources.MaterialLayer.M_REFLECTIVE );
	}
	,
	isMapToShininess : function()
	{
		return this._mapto.testBit( SmitearWebGL.Resources.MaterialLayer.M_SHININESS );
	}
	,
	isMapToAlpha : function()
	{
		return this._mapto.testBit( SmitearWebGL.Resources.MaterialLayer.M_ALPHA );
	}
	,
	isMapToNormal : function()
	{
		return this._mapto.testBit( SmitearWebGL.Resources.MaterialLayer.M_NORMAL );
	}
	,

	/******** inherit method ********/

	_createResource : function()
	{
		this._super();
		
		this.blendMode = null;
		this.mapinput = SmitearWebGL.Resources.MaterialLayer.UV1;
		this.height = 0.05;
		
		/******** private property ********/

		this._mapto = new SmitearWebGL.Core.Math.BitFlags();
		this._mapto.setBit( SmitearWebGL.Resources.MaterialLayer.M_DIFFUSE, true );
		
		this._offset = $V3( 0.0, 0.0, 0.0 );
		this._rotation = $V3( 0.0, 0.0, 0.0 );
		this._scale = $V3( 1.0, 1.0, 1.0 );
		
		this._dOffset = $V3( 0.0, 0.0, 0.0 );
		this._dRotation = $V3( 0.0, 0.0, 0.0 );
		this._dScale = $V3( 0.0, 0.0, 0.0 );
		
		this._texture = null;
		this._matrix = null;
		
		this._transformDirty = false;
	}
	,
	_destroyResource : function()
	{
		this._super();
		
		this.blendMode = null;
		this._mapto = null;
		this._offset = null;
		this._rotation = null;
		this._scale = null;
		this._dOffset = null;
		this._dRotation = null;
		this._dScale = null;
		this._texture = null;
		this._matrix = null;
	}
}
);

SmitearWebGL.Resources.MaterialLayer.M_DIFFUSE = 0;
SmitearWebGL.Resources.MaterialLayer.M_HEIGHT = 1;
SmitearWebGL.Resources.MaterialLayer.M_SPECULAR = 2;
SmitearWebGL.Resources.MaterialLayer.M_EMISSIVE = 3;
SmitearWebGL.Resources.MaterialLayer.M_MASK = 4;
SmitearWebGL.Resources.MaterialLayer.M_REFLECTIVE = 5;
SmitearWebGL.Resources.MaterialLayer.M_SHININESS = 6;
SmitearWebGL.Resources.MaterialLayer.M_ALPHA = 7;
SmitearWebGL.Resources.MaterialLayer.M_NORMAL = 8;

SmitearWebGL.Resources.MaterialLayer.UV1 = 0;
SmitearWebGL.Resources.MaterialLayer.UV2 = 1;
SmitearWebGL.Resources.MaterialLayer.MAP_NORM = 2;
SmitearWebGL.Resources.MaterialLayer.MAP_OBJ = 3;
SmitearWebGL.Resources.MaterialLayer.MAP_REF = 4;
SmitearWebGL.Resources.MaterialLayer.MAP_ENV = 5;
SmitearWebGL.Resources.MaterialLayer.MAP_VIEW = 6;

SmitearWebGL.Resources.MaterialLayer.BL_MIX = 0;
SmitearWebGL.Resources.MaterialLayer.BL_MUL = 1;